<?php

//not sure if we should namespace this - I like the global \E::...
//namespace EIP;
class ExceptionControllerNotFound extends \Exception{};
class ExceptionFileNotFound extends \Exception{};

$log_ins = array();
$EIP_SETTINGS=null;

class E {
	
	static public function redirect($url) {
		E::get_logger()->debug("Redirecting to '{$url}");
		header("Location: {$url}");
		exit;
	}
	static public function get_raw_url($url) {
		return (E::get_setting('core.base_url','')=='') ? '/'.$url : sprintf("/%s/%s",$url);
	}
	
	static public function get_url($controller,$action='',$queryString='') {
		if($queryString && $queryString[0] != '?')
			$queryString='?'.$queryString;
		return (E::get_setting('core.base_url','')=='') ? sprintf("/%s/%s%s",$controller,$action,$queryString) : sprintf("/%s/%s/%s%s",E::get_setting('core.base_url',''),$controller,$action,$queryString);
	}
	
	static public function load_site_settings($settings=null) {
		if($EIP_SETTINGS=null) {
			//load cache settings
			require_once(BASE_DIRECTORY.'configs/core.php');	
			E::load_site_settings('Core/static_page');
		}
		
		if($settings and file_exists(BASE_DIRECTORY.'/'.$settings.'.php')) {
			if (!E::get_setting('core.cache_settings',false)) //if true, settings will be loaded by controllerbase from cache
			{
				//load config and cache if if we suppose to
				require_once(BASE_DIRECTORY.'/'.$settings.'.php');
			}
		}
	}
	
	static public function get_logger($name="root",$settings=null) {
		global $log_ins;
		if(!isset($log_ins[$name]))
		{
			if($name=="root")
				Logger::configure(BASE_DIRECTORY.'/configs/log4php.xml');
			$log_ins[$name] = Logger::getLogger($name);
		}
		return $log_ins[$name];
	}
	
	static public function update_settings($path,$value,$desc=null) {
		$EIP_SETTINGS[$path]=$value;
		if(E::get_setting('core.debug_mode'))
		{
			if(!isset($EIP_DESCRIPTIONS))
			{
				$EIP_DESCRIPTIONS=array();
			}
			$EIP_DESCRIPTIONS[$path]=$desc;
		}
	}
	
	static public function update_settings_byRef($path,&$value) {
		$EIP_SETTINGS[$path]=$value;
	}
	
	static public function get_setting($path,$default=false) {
		if(isset($EIP_SETTINGS[$path]))
			return $EIP_SETTINGS[$path];
		return $default;
	}

	static public function load_controller($name) {
		global $action;
		$logger=@E::get_logger();
		$logger->debug("Try to load Class: '{$name}' as a controller.");
		$controller_name = E::getFullControllerClassName($name,$action);
		$logger->debug("Returned '{$controller_name}' as Full Class Name.");
		if($controller_name) {
			include_once(BASE_DIRECTORY.'/controllers/'.$controller_name.'.php' );
			$logger->debug("Loaded '{$controller_name}' from '".BASE_DIRECTORY.'/controllers/'.$controller_name.'.php\'');
			if(!class_exists($controller_name) && strpos($controller_name,'/')>0)//something changed
			{
				$name_tokens = preg_split('#/#',$controller_name);
				$short_name = (count($name_tokens) > 1) ? $name_tokens[count($name_tokens)-1] : null;
				if ($short_name != null && class_exists($short_name))
				{
					class_alias($short_name,$controller_name);
					$logger->debug("Aliased '{$controller_name}' as '{$short_name}'");
				}
			}
		}
	}
	static public function load_model($name) {
		
		if(preg_match('#Model_(.*?)#', $name,$matches)) {
			$logger=@E::get_logger();
			$logger->info("Try to load Model: '{$name}' as a controller.");
			if( file_exists("{BASE_DIRECTORY}/models/{$matches[1]}.php") )
			{
				require_once("{BASE_DIRECTORY}/models/{$matches[1]}.php");
				if(!class_exists($name) && strpos($name,'/')>0)
				{
					$name_tokens = preg_split('#/#',$name);
					$short_name = (count($name_tokens) > 1) ? $name_tokens[count($name_tokens)-1] : null;
					if ($short_name != null && class_exists($short_name))
					{
						class_alias($short_name,$name);
						$logger->info("Aliased '{$name}' as '{$short_name}'");
					}	
				}
			}
		}
	}
	static public function load_core($name) {
		if ( file_exists ( BASE_DIRECTORY.'/lib/'.$name.'.php' ) ) 
		{
			E::get_logger()->info("Loading Core Library: '{$name}'");
			include_once( BASE_DIRECTORY.'/lib/'.$name.'.php' );
		}
	}
	static public function getFullControllerClassName(&$name,&$action) {
		
		if ( file_exists(BASE_DIRECTORY.'/controllers/'.$name.'/'.$action.'.php') ) //subcontrollers
		{
			$oa = $action;
			$action = 'Index';
			return sprintf("%s/%s",$name,$oa);
		}
		//subcontroller indexes.... 
		//if true, controller/Main/About/Index.php->Index() will be called
		else if ( file_exists(BASE_DIRECTORY.'/controllers/'.$name.'/Index.php') )
		{
			//possible a index... we could rename the action portion.... but since lets try that in controller
			return $name.'/Index';
		}
		//lastly it check for controller/Main
		//if true, controller/Main->About() will be called
		
		else if(  file_exists ( BASE_DIRECTORY.'/controllers/'.$name.'.php' )  )
		{
			return $name;
		
		}
		//check for weird request... eg /Main/About/Js with action Index.js
		else if( 
			preg_match('#(.*?)/(css|js)$#i',$name,$matches)
			&& isset($matches) 
			&& count($matches)>0 
			&& file_exists(  sprintf("%s/templates/%s/%s/%s",BASE_DIRECTORY,$matches[1],strtolower($matches[2]),$action)  ) 
		)
		{
			$action=strtolower($matches[2]).'/'.$action;
			return $matches[1];
		}
		
		
		return null;
	}
	static public function loadRedBean() {
		if(!defined('EIP_REDBEAN_LOADED')) {
			define('EIP_REDBEAN_LOADED',true);
			require_once('RedBean/rb.php');
			R::setup('sqlite:'.BASE_DIRECTORY .'/dbfile.txt');
		}
	}
	
	
	static public function eip_exception_handler($exception) {
		$logger=@E::get_logger();
		$logger->error("Uncaught exception: ".$exception->getMessage());
		die('I am confused!');
	}
}

E::load_site_settings();

spl_autoload_register(__NAMESPACE__ .'\E::load_controller');
spl_autoload_register(__NAMESPACE__ .'\E::load_core');
set_exception_handler(__NAMESPACE__ .'\E::eip_exception_handler');

?>
